package mybatis.plugins;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 打印mapper语句的id,执行后打印影响的行数。
 * TODO:存储过程
 * @author cgnb_liuxb
 *
 */
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
		@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
				RowBounds.class, ResultHandler.class }),
		@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
				RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class }) })
public class LogResultInterceptor implements Interceptor {
	final Logger logger = LogManager.getLogger(LogResultInterceptor.class);

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement st = (MappedStatement) invocation.getArgs()[0];
		String sqlId = st.getId();
		// 去除包名
		if (sqlId.matches(".*\\.(\\w+\\.\\w+)$")) {
			sqlId = sqlId.replaceFirst(".*\\.(\\w+\\.\\w+)$", "$1");
		}

		Object rs = null;
		try {
			rs = invocation.proceed();
		} catch (InvocationTargetException e) {
			logger.info("{}异常:{}", sqlId, e.getTargetException());
			throw e;
		} catch (Exception e) {
			logger.info("{}异常:{}", sqlId, e.getMessage());
			throw e;
		}

		try {
			switch (st.getSqlCommandType()) {
			case INSERT:
				logger.info("{}写入{}行", sqlId, rs);
				break;
			case UPDATE:
				logger.info("{}更新{}行", sqlId, rs);
				break;
			case DELETE:
				logger.info("{}删除{}行", sqlId, rs);
				break;
			case SELECT:
				logger.info("{}查询{}行", sqlId, rs == null ? null : ((List<?>) rs).size());
				break;
			default:
				break;
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return rs;
	}

	@Override
	public Object plugin(Object arg0) {
		return Plugin.wrap(arg0, this);
	}

	@Override
	public void setProperties(Properties arg0) {

	}

}
